package com.superbytecode.cloud.common.result;

import com.superbytecode.cloud.common.exception.ErrorCodeEnum;
import com.superbytecode.cloud.common.exception.IErrorCode;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;

import java.util.Map;

/**
 * All rights Reserved, Designed By www.super-master.com
 *
 * @ProjectName: beacon-cloud
 * @Package: com.superbytecode.cloud.common.model.res
 * @ClassName: ResultWrapper
 * @Description: []
 * <p> </p>
 * @Author: [Lance Ting]
 * @Date: 2024/10/21 16:50
 * @Version: V1.0
 * @Copyright: 2024 www.super-master.cn Inc. All rights reserved.
 * TODO: 注意,本文件Lance Ting所作,如果转载或使用请标明具体出处!
 **/
@Data
@Builder
public class ResultWrapper<T> {
    /**
     * @see com.superbytecode.cloud.common.exception.ErrorCodeEnum
     */
    @ApiModelProperty("结果状态码")
    private String code;
    /**
     *
     */
    @ApiModelProperty("返回消息")
    private String message;
    /**
     *
     */
    @ApiModelProperty("返回数据")
    private T data;
    /**
     * 返回扩展数据
     */
    @ApiModelProperty("返回扩展数据")
    private Map<String, Object> ext;
    /**
     *
     */
    @ApiModelProperty("链路id")
    private String traceId;

    // -----------------------------------------------------------------------------------------------------------------
    public ResultWrapper(String code, String message) {
        this.code = code;
        this.message = message;
        this.setTraceId();
    }

    public ResultWrapper(IErrorCode resultCode) {
        this(resultCode.getCode(), resultCode.getMessage());
    }

    public ResultWrapper(IErrorCode resultCode, T data) {
        this(resultCode);
        this.data = data;
    }

    // -----------------------------------------------------------------------------------------------------------------
    public static <T> ResultWrapper<T> success() {
        return success(null);
    }

    public static <T> ResultWrapper<T> success(T data) {
        return new ResultWrapper<>(ErrorCodeEnum.SUCCESS, data);
    }


    public static ResultWrapper<Void> failure(IErrorCode errorCode, String detailErrorMsg) {
        return failure(errorCode.getCode(), errorCode.getMessage() + "：" + detailErrorMsg);
    }

    public static <T> ResultWrapper<T> failure(IErrorCode errorCode) {
        return failure(errorCode.getCode(), errorCode.getMessage());
    }

    public static <T> ResultWrapper<T> failure(String code, String message) {
        return new ResultWrapper<>(code, message);
    }

    // -----------------------------------------------------------------------------------------------------------------
    @Trace
    public void setTraceId() {
        this.traceId = TraceContext.traceId();
    }
}